/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.giant.bean.transactions;

import com.giant.authentication.User;
import com.giant.bean.ReporteController;
import com.giant.bean.parametrics.ClassBean;
import com.giant.bean.parametrics.LineBean;
import com.giant.entities.InDetOrder;
import com.giant.entities.InOrder;
import com.giant.entities.InShipment;
import com.giant.entities.pos.PInvoice;
import com.giant.exceptions.OperacionInvalidaException;
import com.giant.services.IServicioPersistenciaLocal;
import com.giant.services.ServicioPersistencia;
import com.giant.services.views.ServiceInventoryVLocal;
import com.giant.services.transactions.ServiceOrderLocal;
import com.giant.views.InInventoryV;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.transaction.UserTransaction;
import org.primefaces.model.StreamedContent;

/**
 *
 * @author Harold
 */
@ManagedBean
@SessionScoped
public class OrderBean implements Serializable {

    /**
     * Relación con la interfaz que provee los servicios necesarios del vendedor
     */
    @EJB
    private ServiceInventoryVLocal serviceInventory;
    @EJB
    private ServiceOrderLocal serviceOrder;
    @EJB
    private IServicioPersistenciaLocal persistence;
    private String param = "";
    private String desc2param = "";
    private String sku = "";
    private List<InInventoryV> allInventories;
    @ManagedProperty(value = "#{lineBean}")
    private LineBean lineBean;
    @ManagedProperty(value = "#{classBean}")
    private ClassBean classBean;
    @ManagedProperty(value = "#{detOrderBean}")
    private DetOrderBean detOrderBean;
    @Resource
    UserTransaction utx;
    //-----------------------------------------------------------
    // Atributos
    //-----------------------------------------------------------
    InOrder tempOrder = new InOrder();
    /**
     * Representa un nuevo vendedor a ingresar
     */
    private InInventoryV inventory = new InInventoryV();
    private List<InInventoryV> tempDetailOrder;
    //listar ordenes
    private List<InOrder> allOrders;
    private boolean editing = false;
    private int numOrder;
    private int id_user = 0;
    private boolean isAdmin = false;
    private List<InOrder> filterInventory;
    //-----------------------------------------------------------
    // Getters y setters
    //-----------------------------------------------------------

    public OrderBean() {

        persistence = new ServicioPersistencia();
        //Traer el usuario que esta registrado
        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        Map<String, Object> sessionMap = externalContext.getSessionMap();
        User user = (User) sessionMap.get("user");
        id_user = user.getIdUser();
        isAdmin = (Boolean) sessionMap.get("isAdmin");
    }

    /**
     * Devuelve el objeto de vendedor actual
     *
     * @return vendedor Vendedor actual
     */
    public InInventoryV getInInventory() {
        return inventory;
    }

    /**
     * Modifica al vendedor actual
     *
     * @param vendedor Nuevo vendedor
     */
    public void setInventoryV(InInventoryV inventory) {
        this.inventory = inventory;
    }

    /**
     * Devuelve todos los vendedores del sistema
     *
     * @return vendedores Lista con todos los vendedores del sistema
     */
    public List<InInventoryV> getInventories() {
        if (allInventories == null) {
            allInventories = serviceInventory.getInventoryV();
        }
        return allInventories;
    }

    public void handleCityChange(String sql, String param) {
        Map<String, String> map = new HashMap<String, String>();
        map.put(param, this.param);
        allInventories = this.serviceInventory.getInventoryVFilter(sql, map);
    }

    public void filterCriteria() {
        System.out.println(getClassBean().getLineParam() + "-" + getClassBean().getDescParam() + "-" + getClassBean().getDescParam2());
        String query = "SELECT i FROM InInventoryV i where 1=1";

        if (getClassBean().getLineParam() != null && !getClassBean().getLineParam().equals("")) {
            query += " and i.idLine.inLinePK.idLine =" + getClassBean().getLineParam();
        }

        if (getClassBean().getDescParam() != null && !getClassBean().getDescParam().equals("")) {
            query += " and i.idClass.description ='" + getClassBean().getDescParam() + "'";
        }

        if (getClassBean().getDescParam2() != null && !getClassBean().getDescParam2().equals("")) {
            query += " and i.idClass.description2 ='" + getClassBean().getDescParam2() + "'";
        }
        if (getSku() != null && !getSku().equals("")) {
            query += " and i.sku ='" + getSku() + "'";
        }


        System.out.println(query);
        allInventories = persistence.executeObjectSql(query);
    }

    public StreamedContent generateReport() {
        StreamedContent file = null;
        try {

            String whereLine = "", whereClass = "", whereCatalog = "", whereSku = "";

            if (getClassBean().getLineParam() != null && !getClassBean().getLineParam().equals("")) {
                whereLine = "whereLine= and tab0.id_line =" + getClassBean().getLineParam()+"&";
            }

            if (getClassBean().getDescParam() != null && !getClassBean().getDescParam().equals("")) {
                whereClass = "whereClass= and tab0.class_desc ='" + getClassBean().getDescParam() + "'&";
            }

            if (getClassBean().getDescParam2() != null && !getClassBean().getDescParam2().equals("")) {
                whereCatalog = "whereCatalog= and tab0.class_desc2 ='" + getClassBean().getDescParam2() + "'&";
            }
            if (getSku() != null && !getSku().equals("")) {
                whereSku = "whereSku= and tab0.sku ='" + getSku() + "'&";
            }
            
            String jasperParameters = whereLine+whereClass+whereCatalog+whereSku;
            if(!jasperParameters.equals(""))
            {
                jasperParameters=jasperParameters.substring(0, jasperParameters.length()-1);
            }
            //generate jasper
            ReporteController rc = new ReporteController();
            file = rc.getFile("allInventory", jasperParameters, "order", "AllInventory");

        } catch (IOException ex) {
            Logger.getLogger(OrderBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        return file;

    }

    public String getParam() {
        return param;
    }

    public void setParam(String param) {
        this.param = param;
    }

    public void addTempDetailOrder(InInventoryV inv) {
        if (tempDetailOrder == null) {
            tempDetailOrder = new ArrayList<InInventoryV>();
        }
        if (inv.getOrderQuantity() <= inv.getAvailableQuantity() && inv.getOrderQuantity() >= 0) {

            if (inv.getOrderQuantity() > 0) {
                boolean finded = false;
                for (int i = 0; i < tempDetailOrder.size() && finded == false; i++) {
                    InInventoryV inInventoryV = tempDetailOrder.get(i);

                    if (inv.getSku().equals(inInventoryV.getSku())) {
                        inInventoryV.setOrderQuantity(inv.getOrderQuantity());
                        finded = true;
                    }
                }

                if (finded == false) {
                    tempDetailOrder.add(inv);
                }

            } else {
                tempDetailOrder.remove(inv);
            }
        } else {
            inv.setOrderQuantity(0);
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Error", "The stock available quantity is " + inv.getAvailableQuantity() + "!"));
        }

        // System.out.println("list size: " + tempDetailOrder.size());
    }

    public String createDetailOrders() {
        System.out.println("createDetailOrders()");
        if (tempDetailOrder != null && tempDetailOrder.size() > 0) {
            //TODO HARD CODED setIdPos idperson numdoc obvservations
            tempOrder.setIdPos(1);
            tempOrder.setIdUser(id_user);
            tempOrder.setIdPerson(1);
            tempOrder.setNumDoc("0001");
            tempOrder.setDateOrder(new Date());
            tempOrder.setObservations("obv");
            tempOrder.setStatus(true);
            tempOrder.setPayment(false);

            List ship = persistence.executeObjectSql("SELECT i FROM InShipment i WHERE i.idShipment =1");
            InShipment tempShip = (InShipment) ship.get(0);
            tempOrder.setIdShipment(tempShip);

            InDetOrder det;

            try {
                if (!editing) {
                    //Create order 
                    persistence.create(tempOrder);
                    numOrder = tempOrder.getIdOrder();
                } else {
                    persistence.executeGenericSQLAdd("delete from in_det_order where id_order=" + numOrder);
                    //Get id order     
//                final int ord = Integer.parseInt(persistence.executeGenericSQL("select ifnull(max(id_order),0) as max from in_order").get(0) + "");
                }

                //Create order details
                for (int i = 0; i < tempDetailOrder.size(); i++) {

                    InInventoryV inv = tempDetailOrder.get(i);

                    det = new InDetOrder();
                    det.setIdOrder(numOrder);
                    //modificar setIdPos
                    det.setIdPos(1);
                    det.setIdBrand(inv.getBrand());
                    det.setIdLine(inv.getLine());
                    det.setIdClass(inv.getClasse());
                    det.setIdCatalog(inv.getCatalog());
                    det.setIdColor(inv.getColor());
                    det.setIdSize(inv.getSize());
                    det.setSku(inv.getSku());
                    det.setQuantity(inv.getOrderQuantity());
                    det.setPriceUnit(inv.getSalePrice());
                    det.setStatus(true);

                    if (inv.getOrderQuantity() > 0) {
                        persistence.create(det);
                    }

                }

                detOrderBean.setNoOrder(numOrder + "");
                detOrderBean.setDateOrder(tempOrder.getDateOrder());
//                detOrderBean.getDetOrders();

            } catch (OperacionInvalidaException ex) {
                Logger.getLogger(OrderBean.class.getName()).log(Level.SEVERE, null, ex);
            }

            return "placeOrder";
        } else {
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Error", "There are not items for the order!"));
        }
        return "";
    }

    public ClassBean getClassBean() {
        return classBean;
    }

    public void setClassBean(ClassBean classBean) {
        this.classBean = classBean;
    }

    public LineBean getLineBean() {
        return lineBean;
    }

    public void setLineBean(LineBean lineBean) {
        this.lineBean = lineBean;
    }

    public void testMethod(String test) {
        System.out.println("realizo test" + test);
    }

    public String getDesc2param() {
        return desc2param;
    }

    public void setDesc2param(String desc2param) {
        this.desc2param = desc2param;
    }

    public DetOrderBean getDetOrderBean() {
        return detOrderBean;
    }

    public void setDetOrderBean(DetOrderBean detOrderBean) {
        this.detOrderBean = detOrderBean;
    }

    public String getSku() {
        return sku;
    }

    public void setSku(String sku) {
        this.sku = sku;
    }

    public List<InOrder> getOrders() {
        if (allOrders == null) {
            allOrders = serviceOrder.getOrder();
        }
        return allOrders;
    }

    public List<InOrder> getClosedOrders() {
        if (allOrders == null) {
            String query = "SELECT i FROM InOrder i WHERE i.status =0";
            System.out.println(query);
            allOrders = persistence.executeObjectSql(query);
//            allDets=serviceDetOrder.getDetOrder();
        }

        return allOrders;
    }

    public StreamedContent closeOrder() throws Exception {
        System.out.println("cerrar orden");
        StreamedContent file = null;
        try {
            utx.begin();
            tempOrder.setStatus(false);
            persistence.update(tempOrder);
            for (int i = 0; i < detOrderBean.getDetOrders().size(); i++) {
                InDetOrder det = detOrderBean.getDetOrders().get(i);
                det.setStatus(false);
                persistence.update(det);
                //Update inventory
                String sql = "update in_inventory set status=0 where sku=" + det.getSku() + " limit " + det.getQuantity();
                persistence.executeGenericSQLAdd(sql);

            }
            utx.commit();
            for (int i = 0; i < tempDetailOrder.size(); i++) {
                tempDetailOrder.get(i).setOrderQuantity(0);
            }

            String jasperParameters = "id_order=" + tempOrder.getIdOrder();
            //generate jasper
            ReporteController rc = new ReporteController();
            file = rc.getFile("orPlaceOrder", jasperParameters, "order", "OrderReport");

        } catch (Exception e) {
            utx.rollback();
        }

        return file;


    }

    public String cancelOrder() {
        System.out.println("cancelar");

        persistence.executeGenericSQLAdd("delete from in_det_order where id_order=" + tempOrder.getIdOrder());
        persistence.executeGenericSQLAdd("delete from in_order where id_order=" + tempOrder.getIdOrder());

        return "Order";
    }

    public String editButton() {
        editing = true;
        return "OrInventory";
    }

    public List<InOrder> getFilterInventory() {
        return filterInventory;
    }

    public void setFilterInventory(List<InOrder> filterInventory) {
        this.filterInventory = filterInventory;
    }
    
    
}
